import { IPSPanelItem } from "@ibiz/dynamic-model-api";
import { IContext, IParams } from "ibiz-core";

/**
 * 表单成员模型
 *
 * @export
 * @class PanelDetailModel
 */
export class PanelDetailModel {

    /**
     * 原始面板项模型
     *
     * @type {IParams}
     * @memberof PanelDetailModel
     */
    public panelItemModel: IPSPanelItem | undefined = undefined;

    /**
     * 面板项下标(上层容器存在多数据容器时启用)
     *
     * @type {number}
     * @memberof PanelDetailModel
     */
    public $index: number = 0;

    /**
     * 当前项数据
     *
     * @type {*}
     * @memberof PanelDetailModel
     */
    protected data: any;

    /**
     * 面板项样式
     *
     * @type {IParams}
     * @memberof PanelDetailModel
     */
    public panelDetailStyle: IParams = {};

    /**
     * 是否有权限
     *
     * @type {boolean}
     * @memberof PanelDetailModel
     */
    public isPower: boolean = true;

    /**
     * 成员标题
     *
     * @type {string}
     * @memberof PanelDetailModel
     */
    public caption: string = '';

    /**
     * 成员类型
     *
     * @type {string}
     * @memberof PanelDetailModel
     */
    public itemType: string = '';

    /**
     * 面板对象
     *
     * @type {*}
     * @memberof PanelDetailModel
     */
    public panel: any = null;

    /**
     * 成员名称
     *
     * @type {string}
     * @memberof PanelDetailModel
     */
    public name: string = '';

    /**
     * 成员是否显示
     *
     * @type {boolean}
     * @memberof PanelDetailModel
     */
    public $visible: boolean = true;

    /**
     * 父项
     *
     * @type {(any | null)}
     * @memberof PanelDetailModel
     */
    public parentItem: any | null = null;

    /**
     * 应用上下文
     *
     * @type {IContext}
     * @memberof PanelDetailModel
     */
    public context: IContext = {};

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof PanelDetailModel
     */
    public viewparams: any = {};

    /**
     * Creates an instance of PanelDetailModel.
     * PanelDetailModel 实例
     * 
     * @param {*} [opts={}]
     * @memberof PanelDetailModel
     */
    constructor(opts: any = {}) {
        this.caption = !Object.is(opts.caption, '') ? opts.caption : '';
        this.itemType = !Object.is(opts.itemType, '') ? opts.itemType : '';
        this.panel = opts.panel ? opts.panel : {};
        this.name = !Object.is(opts.name, '') ? opts.name : '';
        this.$visible = opts.visible ? true : false;
        this.panelItemModel = opts.model ? opts.model : {};
        this.parentItem = opts.parentItem ? opts.parentItem : null;
        this.panelDetailStyle = this.getPanelDetailStyle();
        this.$index = opts.$index;
        this.context = opts.context || {};
        this.viewparams = opts.viewparams || {};
    }

    /**
     * 获取面板样式
     *
     * @memberof PanelDetailModel
     */
    protected getPanelDetailStyle() {
        let panelDetailStyle = {};
        // 文本换行模式
        // 垂直对齐/垂直对齐（自身）
        // 宽度模式/高度模式
        // 上、下、左、右侧间隔
        // 水平对齐/水平对齐（自身）
        // 边框样式
        return panelDetailStyle;
    }

    /**
     * 设置成员是否隐藏
     *
     * @memberof PanelDetailModel
     */
    public set visible(val: boolean) {
        if (this.isPower) {
            this.$visible = val;
        }
    }

    /**
     * 获取成员是否隐藏
     *
     * @memberof PanelDetailModel
     */
    public get visible() {
        return this.$visible;
    }


    /**
     * 设置显示与隐藏
     *
     * @param {boolean} state
     * @memberof PanelDetailModel
     */
    public setVisible(state: boolean): void {
        if (this.isPower) {
            this.visible = state;
        }
    }

    /**
     * 执行异步逻辑
     *
     * @memberof PanelDetailModel
     */
    public async loaded() { }

    /**
     * 获取数据
     *
     * @return {*} 
     * @memberof PanelDetailModel
     */
    public getData() {
        return this.data;
    }

    /**
     * 设置数据
     *
     * @param {*} val
     * @memberof PanelDetailModel
     */
    public setData(val: any) { }

    /**
     * 获取面板项样式类
     *
     * @memberof PanelDetailModel
     */
    public getDetailClass() {
        let detailClass = `app-viewlayoutpanel-${this.panelItemModel?.itemType.toLowerCase()}`;
        detailClass += ` viewlayoutpanel-${this.panelItemModel?.itemType.toLowerCase()}-${this.panelItemModel?.name.toLowerCase()}`;
        if (this.panelItemModel?.getPSSysCss?.()) {
            detailClass += ` ${this.panelItemModel?.getPSSysCss?.()?.cssName}`;
        }
        // 容器类型面板
        if (this.panelItemModel?.showCaption) {
            detailClass += ` show-caption`;
        }
        return detailClass;
    }

    /**
     * 获取盒子宽高 TODO 后续需要对宽度、高度模式识别
     *
     * @return {*} 
     * @memberof PanelDetailModel
     */
    public getBoxStyle() {
        const boxStyle = {};
        let layoutPos = this.panelItemModel?.getPSLayoutPos() as any;
        Object.assign(boxStyle, { width: this.panelItemModel?.width ? `${this.panelItemModel.width}px` : '' });
        Object.assign(boxStyle, { height: this.panelItemModel?.height ? `${this.panelItemModel.height}px` : '' });
        // 上方间隔模式
        if (layoutPos.spacingTop) {
            Object.assign(boxStyle, this.getBoxSpacingStyle(layoutPos.spacingTop, 'top'));
        }
        // 下方间隔模式
        if (layoutPos.spacingBottom) {
            Object.assign(boxStyle, this.getBoxSpacingStyle(layoutPos.spacingTop, 'bottom'));
        }
        // 左侧间隔模式
        if (layoutPos.spacingLeft) {
            Object.assign(boxStyle, this.getBoxSpacingStyle(layoutPos.spacingTop, 'left'));
        }
        // 右侧间隔模式
        if (layoutPos.spacingRight) {
            Object.assign(boxStyle, this.getBoxSpacingStyle(layoutPos.spacingTop, 'right'));
        }
        return boxStyle;
    }

    /**
     * 获取盒子间隔样式
     *
     * @private
     * @param {string} spacingType
     * @memberof PanelDetailModel
     */
    private getBoxSpacingStyle(spacingType: string, direction: string) {
        switch (spacingType) {
            case 'OUTERNONE':
                return { [`margin-${direction}`]: '0px' };
            case 'OUTERSMALL':
                return { [`margin-${direction}`]: '8px' };
            case 'OUTERMEDIUM':
                return { [`margin-${direction}`]: '16px' };
            case 'OUTERLARGE':
                return { [`margin-${direction}`]: '24px' };
            case 'INNERNONE':
                return { [`padding-${direction}`]: '0px' };
            case 'INNERSMALL':
                return { [`padding-${direction}`]: '8px' };
            case 'INNERMEDIUM':
                return { [`padding-${direction}`]: '16px' };
            case 'INNERLARGE':
                return { [`padding-${direction}`]: '24px' };
            default:
                return {};
        }
    }

    /**
     * 获取布局设置(约束子)
     *
     * @memberof PanelDetailModel
     */
    public getBoxLayoutStyle() {
        const boxLayoutStyle = {};
        let layout = this.panelItemModel?.getPSLayout() as any;
        if (layout && layout.layout == 'FLEX') {
            const { dir, align, vAlign } = layout;
            Object.assign(boxLayoutStyle, {
                'display': 'flex'
            });
            if (dir) {
                Object.assign(boxLayoutStyle, { 'flex-direction': dir });
            }
            if (align) {
                Object.assign(boxLayoutStyle, { 'justify-content': align });
            }
            if (vAlign) {
                Object.assign(boxLayoutStyle, { 'align-items': vAlign });
            }
        } else {

        }
        return boxLayoutStyle;
    }

    /**
     * 获取自身位置（约束自身）
     *
     * @memberof PanelDetailModel
     */
    public getBoxLayoutPosStyle() {
        const boxLayoutPosStyle = {};
        let layout = this.panelItemModel?.getPSLayout() as any;
        let layoutPos = this.panelItemModel?.getPSLayoutPos() as any;
        // 自身对齐方式
        if (layoutPos.vAlignSelf || layoutPos.hAlignSelf) {
            Object.assign(boxLayoutPosStyle, { 'display': 'flex' });
            // 自身垂直对齐模式
            switch (layoutPos.vAlignSelf) {
                case 'TOP':
                    Object.assign(boxLayoutPosStyle, { 'align-items': 'flex-start' });
                    break;
                case 'MIDDLE':
                    Object.assign(boxLayoutPosStyle, { 'align-items': 'center' });
                    break;
                case 'BOTTOM':
                    Object.assign(boxLayoutPosStyle, { 'align-items': 'flex-end' });
                    break;
                default:
                    break;
            }
            // 自身水平对齐模式
            switch (layoutPos.hAlignSelf) {
                case 'LEFT':
                    Object.assign(boxLayoutPosStyle, { 'justify-content': 'flex-start' });
                    break;
                case 'CENTER':
                    Object.assign(boxLayoutPosStyle, { 'justify-content': 'center' });
                    break;
                case 'RIGHT':
                    Object.assign(boxLayoutPosStyle, { 'justify-content': 'flex-end' });
                    break;
                case 'JUSTIFY':
                    Object.assign(boxLayoutPosStyle, { 'justify-content': 'space-between' });
                    break;
                default:
                    break;
            }
            // 自身垂直对齐模式生效，设置100%高度
            if (layout && layout.layout == 'FLEX' && (layoutPos.vAlignSelf || !this.panelItemModel?.height)) {
                Object.assign(boxLayoutPosStyle, { 'height': '100%' });
            }
            // 自身水平对齐模式，设置100%宽度
            if (layout && layout.layout == 'FLEX' && (layoutPos.hAlignSelf || !this.panelItemModel?.width)) {
                Object.assign(boxLayoutPosStyle, { 'width': '100%' });
            }
        }
        if (layout && layout.layout == 'FLEX') {
            Object.assign(boxLayoutPosStyle, { 'flex-grow': layoutPos?.grow && layoutPos?.grow != -1 ? layoutPos?.grow : 0 });
        }
        return boxLayoutPosStyle;
    }

    /**
     * 获取栅格布局的props
     *
     * @param {*} item 传入项 
     * @param {*} layMode 栅格模式布局 12列/24列
     * @returns {*}
     * @memberof AppDefaultViewLayout
     */
    public getGridLayoutProps(item: any, layMode: string = 'TABLE_24COL'): any {
        let { colXS, colSM, colMD, colLG, colXSOffset, colSMOffset, colMDOffset, colLGOffset } = item.getPSLayoutPos();
        // 设置初始值
        colXS = !colXS || colXS == -1 ? 24 : colXS;
        colSM = !colSM || colSM == -1 ? 24 : colSM;
        colMD = !colMD || colMD == -1 ? 24 : colMD;
        colLG = !colLG || colLG == -1 ? 24 : colLG;
        colXSOffset = !colXSOffset || colXSOffset == -1 ? 0 : colXSOffset;
        colSMOffset = !colSMOffset || colSMOffset == -1 ? 0 : colSMOffset;
        colMDOffset = !colMDOffset || colMDOffset == -1 ? 0 : colMDOffset;
        colLGOffset = !colLGOffset || colLGOffset == -1 ? 0 : colLGOffset;
        if (layMode == 'TABLE_12COL') {
            // 重新计算12列的栅格数值
            colXS = Math.min(colXS * 2, 24);
            colSM = Math.min(colSM * 2, 24);
            colMD = Math.min(colMD * 2, 24);
            colLG = Math.min(colXS * 2, 24);
            // 重新计算12列的栅格偏移
            let sign = (num: number) => (num == 0 ? 0 : num / Math.abs(num));
            colXSOffset = sign(colXSOffset) * Math.min(colXSOffset * 2, 24);
            colSMOffset = sign(colSMOffset) * Math.min(colSMOffset * 2, 24);
            colMDOffset = sign(colMDOffset) * Math.min(colMDOffset * 2, 24);
            colLGOffset = sign(colLGOffset) * Math.min(colLGOffset * 2, 24);
        }
        return {
            xs: { span: colXS, offset: colXSOffset },
            sm: { span: colSM, offset: colSMOffset },
            md: { span: colMD, offset: colMDOffset },
            lg: { span: colLG, offset: colLGOffset },
        };
    }
}